package userserv

import (
	"codedef"
	"encoding/json"
	"fmt"
	"github.com/garyburd/redigo/redis"
	"log"
	"message"
	"net/http"
	"rhelper"
)

func onAddDev2Home(w http.ResponseWriter, r *http.Request) {
	type AddDev2Home struct {
		HomeId string `json:"homeId"`
		Cid    string `json:"cid"`
	}

	type ResponseValue struct {
		Status string `json:"status"`
	}

	var uniqueId string
	if uniqueId = r.Header.Get("uniqueId"); uniqueId == "" {
		log.Println("onAddDev2Home failed, uniqueId is empty")
		replyError(w, codedef.ERR_REQUEST_INVALID_PARAM)
		return
	}

	if r.ContentLength < 1 {
		log.Println("onAddDev2Home failed, content length is zero")
		replyError(w, codedef.ERR_REQUEST_INVALID_PARAM)
		return
	}

	rmessage := make([]byte, r.ContentLength)
	n, _ := r.Body.Read(rmessage)
	if n != int(r.ContentLength) {
		log.Println("onAddDev2Home failed, can't read request body")
		replyError(w, codedef.ERR_REQUEST_INVALID_PARAM)
		return
	}
	log.Println("onAddDev2Home, receive message: ", string(rmessage))

	var addDev2Home AddDev2Home
	err := json.Unmarshal(rmessage, &addDev2Home)
	if err != nil {
		log.Println("onAddDev2Home failed, json decode failed:", err)
		replyError(w, codedef.ERR_DECODE)
		return
	}

	if addDev2Home.HomeId == "" {
		log.Println("onAddDev2Home failed,  homeId is empty")
		replyError(w, codedef.ERR_REQUEST_INVALID_PARAM)
		return
	}

	if addDev2Home.Cid == "" {
		log.Println("onAddDev2Home failed,  cid is empty")
		replyError(w, codedef.ERR_REQUEST_INVALID_PARAM)
		return
	}

	if !isUserDeviceExist(uniqueId, addDev2Home.Cid) {
		log.Println("onAddDev2Home failed, controller not exist ",
			addDev2Home.Cid)
		replyError(w, codedef.ERR_CONTROLLER_NOT_EXIST)
		return
	}

	rconn := rhelper.Pool().Get()
	defer rconn.Close()

	preHomeId, err := redis.String(rconn.Do("HGET", rhelper.ControllerHash+addDev2Home.Cid, "homeId"))
	if err != nil {
		log.Println("addDev2Home, get controller home id error:", err)
		preHomeId = ""
	}

	if preHomeId != "" && preHomeId != addDev2Home.HomeId {
		homeDevices, err := redis.String(rconn.Do("HGET", rhelper.HomeHash+preHomeId, "devices"))
		if err != nil {
			log.Println("get home devices failed, get home devices string error:", err)
		}
		homeDevices = rhelper.CommaStringDelete(homeDevices, rhelper.ControllerHash+addDev2Home.Cid)

		if _, err = rconn.Do("HSET", rhelper.HomeHash+preHomeId, "devices", homeDevices); err != nil {
			log.Println("onAddDev2Home, delete controller from preHome failed:", err)
		}
	}

	if preHomeId != addDev2Home.HomeId {
		devices, err := redis.String(rconn.Do("HGET",
			rhelper.HomeHash+addDev2Home.HomeId,
			"devices"))
		if err != nil && err != redis.ErrNil {
			log.Println("onAddDev2Home failed, get devices err: ", err)
			replyError(w, codedef.ERR_DATABASE)
			return
		}
		devices = rhelper.CommaStringAppend(devices, rhelper.ControllerHash+addDev2Home.Cid)

		rconn.Send("MULTI")
		rconn.Send("HSET", rhelper.HomeHash+addDev2Home.HomeId,
			"devices", devices)
		rconn.Send("HSET", rhelper.ControllerHash+addDev2Home.Cid, "homeId", addDev2Home.HomeId)

		rconn.Do("EXEC")
	}

	replyJSON(w, ResponseValue{Status: "200"})

	ownerInfo, err := getUserInfoById(uniqueId)
	if err != nil {
		log.Println("get userinfo failed, err:", err)
		return
	}

	msgUsers, err := getHomeMemberUserIds(addDev2Home.HomeId)
	if err != nil {
		log.Println("get home member user ids failed, err:", err)
		return
	}
	adminInfo, err := getUserInfoById(msgUsers[0])
	if err != nil {
		log.Println("get userinfo failed, err:", err)
		return
	}

	msgTitle := fmt.Sprintf("%s has shared the air purifier with %s's home", ownerInfo[0], adminInfo[0])
	msgs := message.GenerateMessages(msgUsers, "1", ownerInfo[1], msgTitle, "", 0)
	go message.SendMessage(msgs, "devMessage")
}

func GetHomeAdmin(home_member_key string, conn redis.Conn) string {
	values, err := redis.Strings(conn.Do("ZRANGE", home_member_key, rhelper.HomeAdminSortSetMin, rhelper.HomeAdminSortSetMax))
	if err != nil {
		log.Println("Get home admin failed. err :", err)
	}
	if len(values) == 0 {
		return ""
	}
	//log.Println(values)
	//os.Exit(1)
	return values[0]

}

func init() {
	myMux.muxHandlers.HandleFunc("/addDev2Home", onAddDev2Home)
}
